<template>
  <div class="chart-container">
    <div class="chart-header">
      <h3>数据可视化</h3>
      <div class="chart-controls">
        <!-- 图表类型选择 -->
        <el-tooltip
          content="选择合适的图表类型来展示数据"
          placement="top"
        >
          <el-select 
            v-model="chartType" 
            placeholder="选择图表类型"
            class="chart-select"
          >
            <el-option label="柱状图 (适合比较数值)" value="bar" />
            <el-option label="折线图 (适合展示趋势)" value="line" />
            <el-option label="饼图 (适合展示占比)" value="pie" />
            <el-option label="散点图 (适合分析相关性)" value="scatter" />
            <el-option label="堆叠柱状图 (适合比较组成)" value="stack" />
            <el-option label="双轴图 (适合不同量级)" value="dual" />
          </el-select>
        </el-tooltip>
        
        <!-- 智能推荐按钮 -->
        <el-tooltip content="智能推荐合适的图表类型和字段" placement="top">
          <el-button 
            type="primary" 
            size="default" 
            plain
            @click="autoRecommend"
            :disabled="!columns.length"
          >
            智能推荐
          </el-button>
        </el-tooltip>
        
        <!-- X轴数据选择 -->
        <el-tooltip
          content="选择要在X轴显示的数据列"
          placement="top"
        >
          <el-select 
            v-if="columns.length"
            v-model="xAxis" 
            placeholder="选择X轴数据"
            class="chart-select"
            @change="handleXAxisChange"
          >
            <el-option-group label="推荐字段">
              <el-option 
                v-for="col in recommendedXColumns" 
                :key="`rec-${col}`" 
                :label="`${col} (推荐)`" 
                :value="col"
              >
                <span>{{ col }}</span>
                <small class="column-type recommended">
                  {{ getColumnType(col) }} 
                  <el-icon><Star /></el-icon>
                </small>
              </el-option>
            </el-option-group>
            <el-option-group label="所有字段">
              <el-option 
                v-for="col in columns" 
                :key="col" 
                :label="col" 
                :value="col"
                :disabled="recommendedXColumns.includes(col)"
              >
                <span>{{ col }}</span>
                <small class="column-type">
                  {{ getColumnType(col) }}
                </small>
              </el-option>
            </el-option-group>
          </el-select>
        </el-tooltip>
        
        <!-- Y轴数据选择 -->
        <el-tooltip
          v-if="chartType !== 'pie'"
          content="选择要在Y轴显示的数值列"
          placement="top"
        >
          <el-select 
            v-if="columns.length && chartType !== 'pie'"
            v-model="yAxis" 
            placeholder="选择Y轴数据"
            class="chart-select"
            @change="checkChartAndXAxis"
          >
            <el-option-group label="推荐字段">
              <el-option 
                v-for="col in recommendedYColumns" 
                :key="`rec-${col}`" 
                :label="`${col} (推荐)`" 
                :value="col"
              >
                <span>{{ col }}</span>
                <small class="column-type recommended">
                  数值 
                  <el-icon><Star /></el-icon>
                </small>
              </el-option>
            </el-option-group>
            <el-option-group label="所有数值字段">
              <el-option 
                v-for="col in numericColumns" 
                :key="col" 
                :label="col" 
                :value="col"
                :disabled="recommendedYColumns.includes(col)"
              >
                <span>{{ col }}</span>
                <small class="column-type">数值</small>
              </el-option>
            </el-option-group>
          </el-select>
        </el-tooltip>
        
        <!-- 第二个Y轴 (仅用于双轴图) -->
        <el-tooltip
          v-if="chartType === 'dual'"
          content="选择要在第二个Y轴显示的数值列"
          placement="top"
        >
          <el-select 
            v-model="secondYAxis" 
            placeholder="选择第二Y轴数据"
            class="chart-select"
          >
            <el-option 
              v-for="col in numericColumnsForSecondAxis" 
              :key="col" 
              :label="col" 
              :value="col"
            >
              <span>{{ col }}</span>
              <small class="column-type">数值</small>
            </el-option>
          </el-select>
        </el-tooltip>
        
        <!-- 数据分组选项 (用于堆叠图) -->
        <el-tooltip
          v-if="chartType === 'stack'"
          content="选择用于数据分组的分类列"
          placement="top"
        >
          <el-select 
            v-model="groupBy" 
            placeholder="选择分组依据"
            class="chart-select"
          >
            <el-option 
              v-for="col in categoryColumns" 
              :key="col" 
              :label="col" 
              :value="col"
            >
              <span>{{ col }}</span>
              <small class="column-type">分类</small>
            </el-option>
          </el-select>
        </el-tooltip>
      </div>
    </div>

    <div v-if="showChart" class="chart-wrapper">
      <v-chart :option="chartOption" autoresize />
    </div>
    
    <!-- 提示信息 -->
    <div v-else class="chart-placeholder">
      <el-alert
        v-if="!xAxis && columns.length"
        title="请选择要展示的数据列"
        type="info"
        :closable="false"
      />
      <el-alert
        v-else-if="!yAxis && chartType !== 'pie' && columns.length"
        title="请选择要展示的数值列"
        type="info"
        :closable="false"
      />
    </div>
  </div>
</template>

<script setup>
import { ref, computed, watch, onMounted } from 'vue'
import { use } from 'echarts/core'
import { CanvasRenderer } from 'echarts/renderers'
import { BarChart, LineChart, PieChart, ScatterChart } from 'echarts/charts'
import {
  TitleComponent,
  TooltipComponent,
  LegendComponent,
  GridComponent,
  DataZoomComponent,
  ToolboxComponent
} from 'echarts/components'
import VChart from 'vue-echarts'
import { Star } from '@element-plus/icons-vue'
import { ElMessage } from 'element-plus'

// 注册必要的组件
use([
  CanvasRenderer,
  BarChart,
  LineChart,
  PieChart,
  ScatterChart,
  TitleComponent,
  TooltipComponent,
  LegendComponent,
  GridComponent,
  DataZoomComponent,
  ToolboxComponent
])

const props = defineProps({
  data: {
    type: Array,
    required: true
  },
  columns: {
    type: Array,
    required: true
  }
})

// 默认选择柱状图
const chartType = ref('bar')
const xAxis = ref('')
const yAxis = ref('')
const secondYAxis = ref('') // 用于双轴图
const groupBy = ref('') // 用于堆叠图

// 智能推荐的字段
const recommendedXColumns = ref([])
const recommendedYColumns = ref([])

// 获取数值类型的列
const numericColumns = computed(() => {
  return props.columns.filter(col => {
    // 检查是否为数值类型
    return getColumnType(col) === '数值'
  })
})

// 添加分类列计算属性（用于饼图）
const categoryColumns = computed(() => {
  return props.columns.filter(col => {
    const type = getColumnType(col)
    return type === '分类' || type === '文本'
  })
})

// 获取可用于第二个Y轴的数值列（除了当前选择的第一个Y轴）
const numericColumnsForSecondAxis = computed(() => {
  return numericColumns.value.filter(col => col !== yAxis.value)
})

// 判断是否显示图表
const showChart = computed(() => {
  if (chartType.value === 'pie') {
    return !!xAxis.value
  } else if (chartType.value === 'dual') {
    return !!xAxis.value && !!yAxis.value && !!secondYAxis.value
  } else if (chartType.value === 'stack') {
    return !!xAxis.value && !!yAxis.value && !!groupBy.value
  }
  return !!xAxis.value && !!yAxis.value
})

// 生成图表配置
const chartOption = computed(() => {
  if (!showChart.value) return {}

  switch (chartType.value) {
    case 'bar':
      return getBarOption()
    case 'line':
      return getLineOption()
    case 'pie':
      return getPieOption()
    case 'scatter':
      return getScatterOption()
    case 'stack':
      return getStackOption()
    case 'dual':
      return getDualAxisOption()
    default:
      return {}
  }
})

// 柱状图配置
const getBarOption = () => {
  const xData = props.data.map(item => item[xAxis.value])
  const yData = props.data.map(item => item[yAxis.value])

  return {
    title: {
      text: `${xAxis.value} vs ${yAxis.value}`
    },
    tooltip: {
      trigger: 'axis'
    },
    xAxis: {
      type: 'category',
      data: xData
    },
    yAxis: {
      type: 'value'
    },
    series: [{
      data: yData,
      type: 'bar'
    }]
  }
}

// 折线图配置
const getLineOption = () => {
  const xData = props.data.map(item => item[xAxis.value])
  const yData = props.data.map(item => item[yAxis.value])

  return {
    title: {
      text: `${xAxis.value} vs ${yAxis.value}`
    },
    tooltip: {
      trigger: 'axis'
    },
    xAxis: {
      type: 'category',
      data: xData
    },
    yAxis: {
      type: 'value'
    },
    series: [{
      data: yData,
      type: 'line',
      smooth: true
    }]
  }
}

// 饼图配置
const getPieOption = () => {
  // 按选定的列进行分组统计
  const groupedData = props.data.reduce((acc, item) => {
    const key = item[xAxis.value]
    if (!acc[key]) {
      acc[key] = 0
    }
    acc[key]++
    return acc
  }, {})

  const pieData = Object.entries(groupedData).map(([name, value]) => ({
    name,
    value
  }))

  return {
    title: {
      text: `${xAxis.value} 分布`
    },
    tooltip: {
      trigger: 'item',
      formatter: '{b}: {c} ({d}%)'
    },
    legend: {
      orient: 'vertical',
      right: 10,
      top: 'center'
    },
    series: [{
      type: 'pie',
      radius: '50%',
      data: pieData.sort((a, b) => b.value - a.value), // 按数值降序排列
      emphasis: {
        itemStyle: {
          shadowBlur: 10,
          shadowOffsetX: 0,
          shadowColor: 'rgba(0, 0, 0, 0.5)'
        }
      }
    }]
  }
}

// 散点图配置
const getScatterOption = () => {
  const data = props.data.map(item => [item[xAxis.value], item[yAxis.value]])
  
  return {
    title: {
      text: `${xAxis.value} vs ${yAxis.value} 相关性分析`
    },
    tooltip: {
      trigger: 'item',
      formatter: (params) => {
        return `${xAxis.value}: ${params.value[0]}<br/>${yAxis.value}: ${params.value[1]}`
      }
    },
    xAxis: {
      type: getColumnType(xAxis.value) === '数值' ? 'value' : 'category',
      name: xAxis.value,
      nameLocation: 'middle',
      nameGap: 30
    },
    yAxis: {
      type: 'value',
      name: yAxis.value,
      nameLocation: 'middle',
      nameGap: 40
    },
    series: [{
      type: 'scatter',
      data: data,
      symbolSize: 10
    }],
    toolbox: {
      feature: {
        dataZoom: {}
      }
    },
    dataZoom: [
      {type: 'inside'},
      {type: 'slider'}
    ]
  }
}

// 堆叠柱状图配置
const getStackOption = () => {
  // 按分组字段获取唯一值
  const groupValues = [...new Set(props.data.map(item => item[groupBy.value]))]
  
  // 生成x轴分类
  const xData = [...new Set(props.data.map(item => item[xAxis.value]))]
  
  // 为每个分组生成一个系列
  const series = groupValues.map(groupValue => {
    const data = xData.map(xValue => {
      // 找到该分组和x值对应的所有数据行
      const matchingItems = props.data.filter(
        item => item[xAxis.value] === xValue && item[groupBy.value] === groupValue
      )
      
      // 如果有匹配的项，计算y值（可能是多个值的总和）
      if (matchingItems.length) {
        return matchingItems.reduce((sum, item) => sum + (Number(item[yAxis.value]) || 0), 0)
      }
      return 0
    })
    
    return {
      name: String(groupValue),
      type: 'bar',
      stack: 'total',
      data
    }
  })
  
  return {
    title: {
      text: `${xAxis.value} 与 ${yAxis.value} 按 ${groupBy.value} 分组`
    },
    tooltip: {
      trigger: 'axis',
      axisPointer: {
        type: 'shadow'
      }
    },
    legend: {
      orient: 'horizontal',
      bottom: '0%'
    },
    xAxis: {
      type: 'category',
      data: xData
    },
    yAxis: {
      type: 'value'
    },
    series
  }
}

// 双轴图配置
const getDualAxisOption = () => {
  const xData = props.data.map(item => item[xAxis.value])
  const yData = props.data.map(item => item[yAxis.value])
  const y2Data = props.data.map(item => item[secondYAxis.value])
  
  return {
    title: {
      text: `${yAxis.value} 和 ${secondYAxis.value} 对比`
    },
    tooltip: {
      trigger: 'axis',
      axisPointer: {
        type: 'cross'
      }
    },
    legend: {
      data: [yAxis.value, secondYAxis.value]
    },
    xAxis: {
      type: 'category',
      data: xData
    },
    yAxis: [
      {
        type: 'value',
        name: yAxis.value,
        position: 'left'
      },
      {
        type: 'value',
        name: secondYAxis.value,
        position: 'right'
      }
    ],
    series: [
      {
        name: yAxis.value,
        type: 'bar',
        data: yData
      },
      {
        name: secondYAxis.value,
        type: 'line',
        yAxisIndex: 1,
        data: y2Data
      }
    ]
  }
}

// 智能推荐图表和字段
const autoRecommend = () => {
  if (!props.data.length || !props.columns.length) {
    ElMessage.warning('没有足够的数据来进行推荐')
    return
  }
  
  // 重置推荐结果
  recommendedXColumns.value = []
  recommendedYColumns.value = []
  
  // 检查所有列的数据特征
  const columnFeatures = analyzeColumns()
  
  // 推荐X轴的字段（优先选择日期、低基数分类或索引字段）
  const dateColumns = props.columns.filter(col => getColumnType(col) === '日期')
  const categoryColumnsArr = props.columns.filter(col => {
    const type = getColumnType(col)
    return type === '分类' && columnFeatures[col].uniqueValues <= 15
  })
  
  // 如果有日期列，优先推荐作为X轴
  if (dateColumns.length) {
    recommendedXColumns.value = dateColumns
    chartType.value = 'line' // 时间序列适合折线图
  } 
  // 否则如果有合适的分类列，推荐作为X轴
  else if (categoryColumnsArr.length) {
    recommendedXColumns.value = categoryColumnsArr
    // 根据分类数量选择适合的图表类型
    if (categoryColumnsArr.length > 1 && numericColumns.value.length >= 1) {
      chartType.value = 'stack'
      groupBy.value = categoryColumnsArr[1] // 使用第二个分类列作为分组依据
    } else {
      chartType.value = 'bar'
    }
  }
  
  // 对于Y轴，推荐具有高变异性的数值列
  const numColumnsWithVariance = numericColumns.value
    .map(col => ({
      name: col,
      variance: columnFeatures[col].variance
    }))
    .sort((a, b) => b.variance - a.variance) // 按方差降序排序
  
  if (numColumnsWithVariance.length > 0) {
    recommendedYColumns.value = numColumnsWithVariance.map(item => item.name)
    
    // 如果有多个数值列，考虑推荐双轴图
    if (numColumnsWithVariance.length >= 2 && 
        Math.abs(columnFeatures[numColumnsWithVariance[0].name].avg / 
                columnFeatures[numColumnsWithVariance[1].name].avg) > 10) {
      chartType.value = 'dual'
      secondYAxis.value = numColumnsWithVariance[1].name
    }
  }
  
  // 设置推荐的字段
  if (recommendedXColumns.value.length > 0) {
    xAxis.value = recommendedXColumns.value[0]
  }
  
  if (recommendedYColumns.value.length > 0) {
    yAxis.value = recommendedYColumns.value[0]
  }
  
  // 根据数据特征智能选择最合适的图表类型
  if (recommendedXColumns.value.length === 0 && recommendedYColumns.value.length >= 2) {
    // 如果没有合适的X轴但有多个数值列，推荐散点图做相关性分析
    chartType.value = 'scatter'
    xAxis.value = numColumnsWithVariance[0].name
    yAxis.value = numColumnsWithVariance[1].name
  } else if (recommendedXColumns.value.length === 0 && numericColumns.value.length === 0) {
    // 如果没有合适的X轴和Y轴，但有分类列，使用饼图
    const categoryCol = props.columns.find(col => getColumnType(col) === '分类' || getColumnType(col) === '文本')
    if (categoryCol) {
      chartType.value = 'pie'
      xAxis.value = categoryCol
    }
  }
  
  ElMessage.success('已根据数据特征智能推荐图表类型和字段')
}

// 分析列的数据特征
const analyzeColumns = () => {
  const features = {}
  
  props.columns.forEach(col => {
    const values = props.data.map(item => item[col]).filter(v => v != null)
    const uniqueValues = new Set(values).size
    
    features[col] = {
      uniqueValues,
      type: getColumnType(col)
    }
    
    // 对数值列计算更多统计特征
    if (features[col].type === '数值') {
      const numValues = values.map(v => Number(v))
      const sum = numValues.reduce((acc, val) => acc + val, 0)
      const avg = sum / numValues.length
      
      // 计算方差
      const variance = numValues.reduce((acc, val) => acc + Math.pow(val - avg, 2), 0) / numValues.length
      
      features[col].avg = avg
      features[col].min = Math.min(...numValues)
      features[col].max = Math.max(...numValues)
      features[col].variance = variance
    }
  })
  
  return features
}

// X轴改变时调整Y轴选择和图表类型
const handleXAxisChange = () => {
  // 如果选择的是日期类型的X轴，默认使用折线图
  if (getColumnType(xAxis.value) === '日期' && yAxis.value) {
    chartType.value = 'line'
  }
  
  // 检查图表类型与轴选择的一致性
  checkChartAndXAxis()
}

// 检查图表类型与轴选择是否一致
const checkChartAndXAxis = () => {
  const xType = getColumnType(xAxis.value)
  
  // 如果选择了饼图但X轴不是分类/文本型，提示并调整
  if (chartType.value === 'pie' && !(xType === '分类' || xType === '文本')) {
    ElMessage.warning('饼图通常适合展示分类数据，已自动调整为柱状图')
    chartType.value = 'bar'
  }
  
  // 如果X轴和Y轴都是数值型，推荐使用散点图
  if (xType === '数值' && yAxis.value && getColumnType(yAxis.value) === '数值') {
    ElMessage({
      message: '检测到X轴和Y轴都是数值型，散点图可能更适合展示相关性',
      type: 'info',
      showClose: true,
      duration: 3000
    })
  }
}

// 监听变化重置选项
watch(chartType, () => {
  if (chartType.value === 'pie') {
    yAxis.value = ''
  } else if (chartType.value === 'dual' && !secondYAxis.value && numericColumnsForSecondAxis.value.length) {
    secondYAxis.value = numericColumnsForSecondAxis.value[0]
  } else if (chartType.value === 'stack' && !groupBy.value && categoryColumns.value.length) {
    groupBy.value = categoryColumns.value[0]
  }
})

// 组件挂载时自动分析数据提供推荐
onMounted(() => {
  if (props.data.length && props.columns.length) {
    // 延迟执行，确保数据已加载
    setTimeout(() => {
      autoRecommend()
    }, 500)
  }
})

// 获取列的数据类型
const getColumnType = (column) => {
  if (!props.data.length) return ''
  
  // 检查前5条数据以提高准确性
  const sampleSize = Math.min(5, props.data.length)
  const samples = props.data.slice(0, sampleSize).map(item => item[column])
  
  // 如果所有样本都是数字类型
  if (samples.every(value => typeof value === 'number')) {
    return '数值'
  }
  
  // 如果所有样本都是字符串类型
  if (samples.every(value => typeof value === 'string')) {
    // 检查是否都是日期格式
    const isAllDates = samples.every(value => {
      if (!value) return false
      const date = new Date(value)
      return date instanceof Date && !isNaN(date) && 
             // 确保是标准日期格式，而不是普通数字
             value.match(/^(\d{4}[-/]\d{1,2}[-/]\d{1,2})|(\d{1,2}[-/]\d{1,2}[-/]\d{4})/)
    })
    
    if (isAllDates) return '日期'
    
    // 检查是否可能是分类数据
    const uniqueValues = new Set(samples)
    if (uniqueValues.size <= 10) return '分类'
    
    return '文本'
  }
  
  // 如果存在 null 或 undefined，检查非空值
  const nonNullSamples = samples.filter(value => value != null)
  if (nonNullSamples.length > 0) {
    return getColumnType(nonNullSamples[0])
  }
  
  return '未知'
}
</script>

<style scoped>
.chart-container {
  margin-top: 20px;
  padding: 20px;
  background: var(--card-bg);
  border-radius: 8px;
  border: 1px solid var(--border-color);
}

.chart-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 20px;
}

.chart-controls {
  display: flex;
  gap: 12px;
  flex-wrap: wrap;
}

.chart-wrapper {
  height: 450px;
}

.chart-select {
  min-width: 160px;
}

.column-type {
  margin-left: 8px;
  color: var(--el-text-color-secondary);
  font-size: 12px;
}

.column-type.recommended {
  color: var(--el-color-primary);
  font-weight: bold;
}

.chart-placeholder {
  display: flex;
  justify-content: center;
  align-items: center;
  height: 200px;
}

:deep(.el-select-dropdown__item) {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

:deep(.el-alert) {
  width: fit-content;
}
</style> 